home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 January: Mac OS SDK / Dev.CD Jan 99 SDK1.toast / Development Kits / Mac OS USB DDK_v1.0.1 / Examples / USBModem / ShimSerialHAL.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-03  |  20.9 KB  |  919 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ShimSerialHAL.c
  3.  
  4.     Contains:    Routines for controlling the underlying hardware (HAL - Hardware Abstraction Layer)
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Written by:    
  9.  
  10.     Copyright:    © 1994-1998 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     File Ownership:
  13.  
  14.         DRI:                xxx put dri here xxx
  15.  
  16.         Other Contact:        xxx put other contact here xxx
  17.  
  18.         Technology:            USB
  19.         
  20. */
  21.  
  22. #include    <Gestalt.h>
  23. #include    <Errors.h>
  24.  
  25. #include    "Modem.h"
  26. #include    "ShimSerialHAL.h"
  27. #include    "ModemDriver.h"
  28.  
  29. /************************************************************************************/
  30. //
  31. //    SerHAL_Entry
  32. //
  33. //    This is the main driver entry point.
  34. //
  35. /************************************************************************************/
  36.  
  37. OSErr SerHAL_Entry(UInt16 HdwSelector, ParmBlkPtr pb, UInt32 RefCon)
  38. {
  39. #pragma unused (RefCon)
  40.     OSErr    err = noErr;
  41.     
  42.     switch (HdwSelector)
  43.         {
  44.             case SerHAL_Initialize:
  45.                 // only do the open stuff once per driver pair
  46.                 if (gGlobals->openSession == false)
  47.                      err = HAL_DoOpenSession();
  48.                 break;
  49.                 
  50.             case SerHAL_Terminate:
  51.                 // only do the close stuff once per driver pair
  52.                 if (gGlobals->openSession)
  53.                     err = HAL_DoCloseSession();
  54.                 break;
  55.                 
  56.             case SerHAL_Read:
  57.                 //    attempt to fill read request immediately
  58.                 //    from any pending data in the input buffer
  59.                 err = HAL_FillReadRequest((IOParam*)pb);
  60.                 HAL_InputFlowControl();
  61.                 //    if it's not completed (pending) save the pb
  62.                 if (err > noErr)
  63.                     gGlobals->pbIn = pb;
  64.                 break;
  65.                 
  66.             case SerHAL_Write:
  67.                 err = USBSerialWrite((IOParam*)pb);
  68.                 if (err > noErr)
  69.                     gGlobals->pbOut = pb;
  70.                 break;
  71.                 
  72.             case SerHAL_SetConfiguration:
  73.                 err = HAL_SetConfiguration(*(UInt16*)pb->cntrlParam.csParam);
  74.                 break;
  75.                 
  76.             case SerHAL_SetInputBuffer:
  77.                 err = HAL_SetInputBuffer(*(Ptr*)pb->cntrlParam.csParam, *(UInt16*)(((Ptr)pb->cntrlParam.csParam) + 4));
  78.                 break;
  79.                 
  80.             case SerHAL_SetFlowControl:
  81.                 HAL_SetFlowControl((SerShk*)pb->cntrlParam.csParam, pb->cntrlParam.csCode);
  82.                 break;
  83.                 
  84.             case SerHAL_SetBreak:
  85.                 USBSendBreak((pb->cntrlParam.csCode == kSERDSetBreak));
  86.                 break;
  87.                 
  88.             case SerHAL_SetDTERate:
  89.                 // check csCode first to see what the real rate is
  90.                 if (pb->cntrlParam.csCode == kSERD115KBaud)
  91.                 {
  92.                     *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(115200);
  93.                 } else {
  94.                     if (pb->cntrlParam.csCode == kSERD230KBaud)
  95.                     {
  96.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(23400);
  97.  
  98.                     } else {
  99.                         *(UInt16*)pb->cntrlParam.csParam = HAL_SetDTERate(*(UInt16*)pb->cntrlParam.csParam);
  100.                     }
  101.                 }            
  102.                 break;
  103.                 
  104.             case SerHAL_SetDTR:
  105.                 USBSetDTRState((pb->cntrlParam.csCode == kSERDAssertDTR));
  106.                 USBSetControlLineState();
  107.                 break;
  108.                 
  109.             case SerHAL_SetParity:
  110.                 HAL_SetParity((pb->cntrlParam.csCode == kSERDSetPEAltChar), *(unsigned char*)pb->cntrlParam.csParam, *(((unsigned char*)pb->cntrlParam.csParam)+1));
  111.                 break;
  112.                 
  113.             case SerHAL_SetXOffFlag:
  114.                 HAL_SetXOffFlag(pb->cntrlParam.csCode == kSERDSetXOffFlag);
  115.                 break;
  116.                 
  117.             case SerHAL_SendXOn:
  118.                 HAL_SendXOn((pb->cntrlParam.csCode == kSERDSendXOn));
  119.                 break;
  120.                 
  121.             case SerHAL_SendXOff:
  122.                 HAL_SendXOff((pb->cntrlParam.csCode == kSERDSendXOff));
  123.                 break;
  124.                 
  125.             case SerHAL_Miscellaneous:
  126.                 // only interested in DTR (for now)
  127.                 if ((UInt8)pb->cntrlParam.csParam[0] & kOptionPreserveDTR) 
  128.                 {
  129.                     USBSetCloseDTR();
  130.                 }
  131.                 break;
  132.                 
  133.             case SerHAL_GetBuffer:
  134.                 *(UInt32*)(&pb->cntrlParam.csParam[0]) = HAL_GetBuffer();
  135.                 break;
  136.                 
  137.             case SerHAL_GetStatus:
  138.                 HAL_GetStatus((SerStaRec*)pb->cntrlParam.csParam);
  139.                 break;
  140.                 
  141.             case SerHAL_GetVersion:
  142.                 // need to understand this - 9 implies that we do > 57.6K
  143.                 *(char *)pb->cntrlParam.csParam = 9;
  144.                 break;
  145.                 
  146.             case SerHAL_ControlExtend:
  147.                 err = HAL_ControlExtend(pb);
  148.                 break;
  149.                 
  150.             case SerHAL_StatusExtend:
  151.                 err = HAL_StatusExtend(pb);
  152.                 break;
  153.                 
  154.             default:
  155.                 err = -1;                // unknown selector (for now)
  156.                 break;
  157.         }
  158.     
  159.     return err;
  160. }
  161.  
  162. /************************************************************************************/
  163. //
  164. //    HAL_SetConfiguration
  165. //
  166. //    Serial driver SerReset control call.
  167. //
  168. /************************************************************************************/
  169.  
  170. OSErr HAL_SetConfiguration(UInt16 config)
  171. {
  172.  
  173.     UInt16        baudRate;
  174.     LineParms    Line_Coding;
  175.  
  176.     TraceMessage(0,"\pEntering HAL_SetConfiguration");
  177.     
  178.     switch (config & kSerConfigBaudMask)
  179.     {
  180.         case baud300: baudRate = 300; break;
  181.         case baud600: baudRate = 600; break;
  182.         case baud1200: baudRate = 1200; break;
  183.         case baud1800: baudRate = 1800; break;
  184.         case baud2400: baudRate = 2400; break;
  185.         case baud3600: baudRate = 3600; break;
  186.         case baud4800: baudRate = 4800; break;
  187.         case baud7200: baudRate = 7200; break;
  188.         case baud9600: baudRate = 9600; break;
  189.         case baud19200: baudRate = 19200; break;
  190.         case baud38400: baudRate = 38400; break;
  191.         case baud57600: baudRate = 57600; break;
  192.         default: baudRate = 57600; break;
  193.     }
  194.         
  195.     Line_Coding.DTERate1 = USBToHostWord(baudRate);        // All because of Intel format
  196.     Line_Coding.DTERate2 = 0;
  197.     
  198.     switch (config & kSerConfigLenMask)
  199.     {
  200.         case data5: 
  201.             Line_Coding.DataBits = k5DataBits;
  202.             break;
  203.         case data6: 
  204.             Line_Coding.DataBits = k6DataBits;
  205.             break;
  206.         case data7: 
  207.             Line_Coding.DataBits = k7DataBits;
  208.             break;
  209.         case data8: 
  210.             Line_Coding.DataBits = k8DataBits;
  211.             break;
  212.         default: 
  213.             Line_Coding.DataBits = k8DataBits;
  214.             break;
  215.     }
  216.     
  217.     switch (config & kSerConfigParityMask)
  218.     {
  219.         case noParity: 
  220.             Line_Coding.ParityType = kNoParity;
  221.             break;
  222.         case oddParity: 
  223.             Line_Coding.ParityType = kOddParity;
  224.             break;
  225.         case evenParity: 
  226.             Line_Coding.ParityType = kEvenParity;
  227.             break;
  228.         default: 
  229.             Line_Coding.ParityType = kNoParity;
  230.             break;
  231.     }
  232.     
  233.     switch (config & kSerConfigStopMask)
  234.     {
  235.         case stop10: 
  236.             Line_Coding.CharFormat = k1StopBit;
  237.             break;
  238.         case stop15: 
  239.             Line_Coding.CharFormat = k15StopBits;
  240.             break;
  241.         case stop20: 
  242.             Line_Coding.CharFormat = k2StopBits;
  243.             break;
  244.         default: 
  245.             Line_Coding.CharFormat = k1StopBit;
  246.             break;
  247.     }
  248.     
  249.     //    reset the baud rate and other values
  250.  
  251.     USBSetLineCoding(Line_Coding);
  252.  
  253.     return noErr;
  254. }
  255.  
  256. /************************************************************************************/
  257. //
  258. //    HAL_SetInputBuffer
  259. //
  260. //    Select and initialize the serial input buffer.
  261. //
  262. /************************************************************************************/
  263.  
  264. OSErr HAL_SetInputBuffer(Ptr newBuf, UInt16 bufLen)
  265. {
  266.     OSErr    err;
  267.     long    result;
  268.     Boolean    vmPresent;
  269.         
  270.     TraceMessage(0,"\pEntering HAL_SetInputBuffer");
  271.     
  272.     //  check for presence of virtual memory
  273.     
  274.     err = Gestalt(gestaltVMAttr,&result);
  275.     vmPresent = ((err == noErr) && (result >= gestaltVMPresent));
  276.     
  277.     //  un-hold any previous input buffer
  278.     
  279.     if (vmPresent && gGlobals->inBufPtr && (gGlobals->inBufPtr != gGlobals->builtInBuffer))
  280.         UnholdMemory(gGlobals->inBufPtr, gGlobals->inBufLen);
  281.     
  282.     //    assign our local buffer as the default
  283.     
  284.     gGlobals->inBufPtr = gGlobals->builtInBuffer;
  285.     gGlobals->inBufLen = kBuiltInBufferSize;
  286.     
  287.     //    reset buffer indexes
  288.     
  289.     gGlobals->inBufStartIndex = 0;
  290.     gGlobals->inBufEndIndex = 0;
  291.         
  292.     //    a non-zero buffer length means use client buffer
  293.     //    a zero buffer length means use the default buffer
  294.     
  295.     if (bufLen && newBuf)
  296.     {
  297.         //  we need to make sure the buffer stays in physical memory
  298.         
  299.         if (vmPresent)
  300.         {
  301.             err = HoldMemory(newBuf, bufLen);
  302.             if (err != noErr)
  303.                 return err;
  304.         }
  305.         
  306.         //    assign client buffer
  307.         gGlobals->inBufPtr = (UInt8 *) newBuf;
  308.         gGlobals->inBufLen = bufLen;
  309.     }
  310.     
  311.     return noErr;
  312. }
  313.  
  314. /************************************************************************************/
  315. //
  316. //    HAL_SetFlowControl
  317. //
  318. //    Process the csSerHShake & csSerHShakeDTR control calls.
  319. //
  320. /************************************************************************************/
  321.  
  322. void HAL_SetFlowControl(SerShk *shkNew, UInt16 csCode)
  323. {
  324.     
  325.     TraceMessage(0,"\pEntering HAL_SetFlowControl");
  326.     
  327.     //
  328.     //    set new cts value
  329.     //
  330.  
  331.     gGlobals->serShk.fCTS = shkNew->fCTS;
  332.  
  333.     //
  334.     //    copy over new xon / xoff characters
  335.     //
  336.  
  337.     gGlobals->serShk.xOn = shkNew->xOn;
  338.     gGlobals->serShk.xOff = shkNew->xOff;
  339.  
  340.     //
  341.     //    handle any change in software output flow control
  342.     //    this is ignored for now
  343.  
  344.     gGlobals->serShk.fXOn = 0;
  345.  
  346.     //    copy over the errs & evts options fields
  347.     //    notice we do _nada_ with the events (no _PostEvent, etc.)
  348.     
  349.     gGlobals->serShk.errs = shkNew->errs & (parityErr | hwOverrunErr | framingErr);
  350.     gGlobals->serShk.evts = shkNew->evts;
  351.  
  352.     //    handle any change in software input flow control
  353.     //    again this is ignored for now
  354.  
  355.     gGlobals->serShk.fInX = 0;
  356.  
  357.     //    if csCode is newer kSERDHandshake,
  358.     //    take account of the fDTR field
  359.  
  360.     if (csCode == kSERDHandshake)
  361.     {
  362.         
  363.         //
  364.         //    handle any change in hardware input flow control
  365.         //    ignored for now
  366.         //
  367.  
  368.         gGlobals->serShk.fDTR = 1;
  369.  
  370.     }
  371. }
  372.  
  373. /************************************************************************************/
  374. //
  375. //    HAL_SendXOn
  376. //
  377. //    Determines whether to send XOn character.
  378. //    This is a stub for now
  379. //
  380. /************************************************************************************/
  381.  
  382. void HAL_SendXOn(Boolean always)
  383. {
  384. #pragma unused (always)
  385.  
  386.     TraceMessage(0,"\pEntering HAL_SendXOn");
  387.     
  388. }
  389.  
  390. /************************************************************************************/
  391. //
  392. //    HAL_SendXOff
  393. //
  394. //    Determines whether to send XOff character.
  395. //    This is a stub for now
  396. //
  397. /************************************************************************************/
  398.  
  399. void HAL_SendXOff(Boolean always)
  400. {
  401. #pragma unused (always)
  402.  
  403.     TraceMessage(0,"\pEntering HAL_SendXOff");
  404.  
  405. }
  406.  
  407. /************************************************************************************/
  408. //
  409. //    HAL_SendXOffFlag
  410. //
  411. //    Determines whether to send XOff character.
  412. //
  413. /************************************************************************************/
  414.  
  415. void HAL_SetXOffFlag(Boolean state)
  416. {
  417. #pragma unused (state)
  418.  
  419.     TraceMessage(0,"\pEntering HAL_SetXOffFlag");
  420.     
  421.     gGlobals->serStat.xOffHold = 0;            // always off for now
  422.     
  423. }
  424.  
  425. /************************************************************************************/
  426. //
  427. //    HAL_GetStatus
  428. //
  429. //    Status routine fills in the SerStaRec record.
  430. //
  431. /************************************************************************************/
  432.  
  433. void HAL_GetStatus(SerStaRec *statRec)
  434. {
  435.     
  436.     TraceMessage(0,"\pEntering HAL_GetStatus");
  437.     
  438.     //    get & reset cumErrs
  439.     
  440.     statRec->cumErrs = gGlobals->serStat.cumErrs;
  441.     gGlobals->serStat.cumErrs = 0;
  442.  
  443.     //    has an xOff been sent to stop input?
  444.  
  445.     statRec->xOffSent = gGlobals->serStat.xOffSent;  
  446.  
  447.     //    is there a pending read request? 
  448.  
  449.     statRec->rdPend = (gGlobals->pbIn != nil);
  450.  
  451.     //    is there a pending write request?
  452.  
  453.     statRec->wrPend = (gGlobals->pbOut != nil);
  454.  
  455.     //    cts & xOff output flow control hold flags
  456.  
  457.     statRec->ctsHold = false;                    // always false for now?
  458.     statRec->xOffHold = gGlobals->serStat.xOffHold; 
  459.     
  460. }
  461.  
  462. /************************************************************************************/
  463. //
  464. //    HAL_GetBuffer
  465. //
  466. //    status routine computes & returns the number of bytes pending in the receive buffer 
  467. //
  468. /************************************************************************************/
  469.  
  470. UInt32 HAL_GetBuffer(void)
  471. {
  472.     SInt32    count;
  473.     
  474. //    TraceMessage(0,"\pEntering HAL_GetBuffer");
  475.     
  476.     count = ((SInt32)gGlobals->inBufEndIndex - (SInt32)gGlobals->inBufStartIndex);
  477.     
  478.     if ( count < 0 ) 
  479.         count += gGlobals->inBufLen;
  480.             
  481.     return count;
  482. }
  483.  
  484. /************************************************************************************/
  485. //
  486. //    HAL_SetDTERate
  487. //
  488. /************************************************************************************/
  489.  
  490. UInt16 HAL_SetDTERate(UInt32 baudRate)
  491. {
  492.  
  493.     TraceMessage(0,"\pEntering HAL_SetDTERate");
  494.     
  495.     //    validate the requested baud rate
  496.     
  497.     if (baudRate)
  498.     {
  499.         if (baudRate > kMaxBaudRate)
  500.             baudRate = kMaxBaudRate;
  501.             
  502.         gGlobals->baudRate = baudRate;
  503.     } else {
  504.         baudRate = gGlobals->baudRate;
  505.     }
  506.     
  507.     USBSetBaudRate(baudRate);
  508.     
  509.     //    return actual baud rate used (this is historical)
  510.  
  511.     return baudRate;
  512. }
  513.  
  514. /************************************************************************************/
  515. //
  516. //    HAL_SetParity
  517. //
  518. //    Assigns parity error replacement character and alternate replacment character.
  519. //    if peChar is zero then no parity error character substitution.
  520. //    This is a stub for now
  521. //
  522. /************************************************************************************/
  523.  
  524. void HAL_SetParity(Boolean alt, char peChar, char peAltChar)
  525. {
  526. #pragma unused (alt, peChar, peAltChar)
  527.  
  528.     TraceMessage(0,"\pEntering HAL_SetParity");
  529.  
  530. }
  531.  
  532. /************************************************************************************/
  533. //
  534. //    HAL_FillReadRequest
  535. //
  536. //    Attempts to copy requested bytes from the internal serial buffer into request 
  537. //    parameter block.
  538. //
  539. /************************************************************************************/
  540.  
  541. OSErr HAL_FillReadRequest(IOParam *pb)
  542. {
  543.     OSErr    result;
  544.     UInt16    endIndex;
  545.     UInt16    startIndex;
  546.  
  547.     TraceMessage(0,"\pEntering HAL_FillReadRequest");
  548.  
  549.     result = 1;
  550.     while (result > noErr)
  551.     {
  552.  
  553.         //    this can be interrupted to add data to the internal buffer
  554.         //    so we update inBufStartIndex and inBufEndIndex each time
  555.         //    if there is nothing in the input buffer, leave quietly
  556.  
  557.         endIndex = gGlobals->inBufEndIndex;
  558.         startIndex = gGlobals->inBufStartIndex;
  559.         
  560.         if (startIndex == endIndex) 
  561.             break;
  562.  
  563.         //    copy byte into read request buffer and bump actual count
  564.  
  565.         pb->ioBuffer[pb->ioActCount] = gGlobals->inBufPtr[startIndex];
  566.         pb->ioActCount++;
  567.  
  568.         //    now update internal buffer inBufStartIndex
  569.  
  570.         startIndex++;
  571.         
  572.         if (startIndex >= gGlobals->inBufLen) 
  573.             startIndex = 0;
  574.             
  575.         gGlobals->inBufStartIndex = startIndex;
  576.  
  577.         //    lastly, check if we've satisfied the request
  578.  
  579.         if (pb->ioReqCount <= pb->ioActCount)
  580.             result = noErr;
  581.     }
  582.  
  583.     return result;
  584. }
  585.  
  586. /************************************************************************************/
  587. //
  588. //    HAL_EnableSerialDevice
  589. //
  590. //    Called once at driver open time to configure the hardware and get things going etc.
  591. //
  592. /************************************************************************************/
  593.  
  594. void HAL_EnableSerialDevice(void)
  595. {    
  596.     
  597.     TraceMessage(0,"\pEntering HAL_EnableSerialDevice");
  598.     
  599.     USBSetRTSState(1);
  600.     USBSetDTRState(1);
  601.     
  602.     USBSetControlLineState();
  603.     
  604.     HAL_SetDTERate(0);
  605.  
  606.     // Start the read mechanism
  607.     
  608.     USBStartReadPolling();
  609.     
  610. }
  611.  
  612. /************************************************************************************/
  613. //
  614. //    HAL_DisableSerialDevice
  615. //
  616. //    Called once when the driver is closed to shut things down
  617. //
  618. /************************************************************************************/
  619.  
  620. void HAL_DisableSerialDevice(void)
  621. {
  622.     
  623.     TraceMessage(0,"\pEntering HAL_DisableSerialDevice");
  624.  
  625.     USBStopReadPolling();
  626.  
  627.     USBSetRTSState(0);
  628.     USBSetDTRState(0);
  629.     
  630.     USBSetControlLineState();
  631.     
  632. }
  633.  
  634. /************************************************************************************/
  635. //
  636. //    HAL_InputFlowControl
  637. //
  638. //    Handles hardware (dtr or rts) and software (xon / xoff) input flow control
  639. //    This is a stub for now
  640. //
  641. /************************************************************************************/
  642.  
  643. void HAL_InputFlowControl(void)
  644. {
  645.  
  646.     TraceMessage(0,"\pEntering HAL_InputFlowControl");
  647.  
  648. }
  649.  
  650. /************************************************************************************/
  651. //
  652. //    HAL_EnableInput
  653. //
  654. //    Sets the DTR state
  655. //    This is a stub for now
  656. //
  657. /************************************************************************************/
  658.  
  659. void HAL_EnableInput(Boolean enable)
  660. {
  661. #pragma unused (enable)
  662.  
  663.     TraceMessage(0,"\pEntering HAL_EnableInput");
  664.  
  665. }
  666.  
  667. /************************************************************************************/
  668. //
  669. //    HAL_EnableOutput
  670. //
  671. //    Handles output flow control
  672. //    This is a stub for now
  673. //
  674. /************************************************************************************/
  675.  
  676. void HAL_EnableOutput(void)
  677. {
  678.  
  679.     TraceMessage(0,"\pEntering HAL_EnableOutput");
  680.     
  681. }
  682.  
  683. /************************************************************************************/
  684. //
  685. //    HAL_DoOpenSession
  686. //
  687. //    Process an OpenDriver request to the stub drivers
  688. //
  689. /************************************************************************************/
  690.  
  691. OSErr HAL_DoOpenSession(void)
  692. {
  693.  
  694.     OSErr        err;
  695.     LineParms    Line_Coding;
  696.     
  697.     TraceMessage(0,"\pEntering HAL_DoOpenSession");
  698.     
  699.     // only allow one open session
  700.     
  701.     if (gGlobals->openSession)
  702.         return openErr;
  703.         
  704.     //    reset internal indexes, buffers, etc.
  705.     
  706.     err = HAL_SetInputBuffer(nil, 0);
  707.     if (err)
  708.         return openErr;
  709.     
  710.     //  since we've cleared the buffer to zero initially we have to explicitly
  711.     //  initialize the baudRate
  712.     
  713.     gGlobals->baudRate = kMaxBaudRate;
  714.     
  715.     //    reset default values for other variables
  716.  
  717.     gGlobals->xOnOffChar = 0;
  718.     gGlobals->peChar = 0;
  719.     gGlobals->peAltChar = 0;
  720.  
  721.     //    reset handshake default values as per scc serial driver
  722.  
  723.     gGlobals->serShk.fXOn = 0;
  724.     gGlobals->serShk.fCTS = 1;
  725.     gGlobals->serShk.xOn = 0;
  726.     gGlobals->serShk.xOff = 0;
  727.     gGlobals->serShk.evts = 0;
  728.     gGlobals->serShk.fInX = 0;
  729.     gGlobals->serShk.fDTR = 1;
  730.  
  731.     //    reset serial status record
  732.  
  733.     gGlobals->serStat.cumErrs = 0;
  734.     gGlobals->serStat.xOffSent = 0;
  735.     gGlobals->serStat.rdPend = 0;
  736.     gGlobals->serStat.wrPend = 0;
  737.     gGlobals->serStat.ctsHold = 0;
  738.     gGlobals->serStat.xOffHold = 0;
  739.     
  740.     // Line coding structure
  741.     
  742.     Line_Coding.DTERate1 = 0;            // gets handled later with
  743.     Line_Coding.DTERate2 = 0;            // value from gGlobals->baudRate
  744.     Line_Coding.CharFormat = k1StopBit;
  745.     Line_Coding.ParityType = kNoParity;
  746.     Line_Coding.DataBits = k8DataBits;
  747.     
  748.     InitLineCoding(Line_Coding);
  749.     
  750.     //    Let's get started
  751.     
  752.     HAL_EnableSerialDevice();
  753.     
  754.     // we now have an open session
  755.     
  756.     gGlobals->openSession = true;
  757.         
  758.     return noErr;
  759. }
  760.  
  761. /************************************************************************************/
  762. //
  763. //    HAL_DoCloseSession
  764. //
  765. //    Process a CloseDriver request to the stub drivers
  766. //
  767. /************************************************************************************/
  768.  
  769. OSErr HAL_DoCloseSession(void)
  770. {
  771.  
  772.     TraceMessage(0,"\pEntering HAL_DoCloseSession");
  773.  
  774.     HAL_DisableSerialDevice();
  775.             
  776.     //    reset internal indexes, buffers, etc. - this
  777.     //    is important for vm to unhold memory on any
  778.     //    buffer the client may have requested earlier
  779.     
  780.     HAL_SetInputBuffer(nil, 0);
  781.                     
  782.     // we no longer have an open session
  783.         
  784.     gGlobals->openSession = false;
  785.  
  786.     return noErr;
  787. }
  788.  
  789. /************************************************************************************/
  790. //
  791. //    HAL_ControlExtend
  792. //
  793. //    User extensions to control
  794. //
  795. /************************************************************************************/
  796.  
  797. OSErr HAL_ControlExtend(ParmBlkPtr pb)
  798. {
  799.  
  800.     TraceMessage(0,"\pEntering HAL_ControlExtend");
  801.  
  802.     if (pb->cntrlParam.csCode == kpciGetDCD)
  803.     {
  804.         ((char *)(pb->cntrlParam.csParam))[6] = USBGetDCDValue();
  805.         return noErr;
  806.     }
  807.     
  808.     return controlErr;
  809. }
  810.  
  811. /************************************************************************************/
  812. //
  813. //    HAL_StatusExtend
  814. //
  815. //    User extensions to status
  816. //
  817. /************************************************************************************/
  818.  
  819. OSErr HAL_StatusExtend(ParmBlkPtr pb)
  820. {
  821. #pragma unused (pb)
  822.  
  823.     TraceMessage(0,"\pEntering HAL_StatusExtend");
  824.     
  825.     return statusErr;
  826. }
  827.  
  828.  
  829. /************************************************************************************/
  830. //
  831. //    HAL_ShimInput
  832. //
  833. //    Handles the coordination of input and the requestors buffer.
  834. //
  835. /************************************************************************************/
  836.  
  837. void HAL_ShimInput(UInt8 *buf, UInt32 count)
  838. {
  839.     IOParam                 *pb;
  840.     OSErr                    result;
  841.     register UInt16            nextIndex;
  842.     register unsigned char    rcvByte;
  843.     unsigned char            cumErrs;
  844.     
  845.     TraceMessage(0,"\pEntering ShimInput");
  846.         
  847.     //    set return result to incomplete
  848.  
  849.     result = 1;
  850.     cumErrs = 0;
  851.  
  852.     while (count--)
  853.     {
  854.  
  855.         //  handle reading of data available in the hardware receive buffer
  856.         
  857.         rcvByte = *buf++;
  858.                             
  859.         //    compute index into our input buffer
  860.  
  861.         nextIndex = gGlobals->inBufEndIndex + 1;
  862.         if ( nextIndex >= gGlobals->inBufLen ) 
  863.             nextIndex = 0;
  864.             
  865.         //    stuff the character into the input buffer and update the index
  866.  
  867.         gGlobals->inBufPtr[gGlobals->inBufEndIndex] = rcvByte;
  868.         gGlobals->inBufEndIndex = nextIndex;
  869.  
  870.         //    check for input buffer overflow
  871.  
  872.         if (gGlobals->inBufEndIndex == gGlobals->inBufStartIndex)
  873.         {
  874.             //    mark that we've had an overrun
  875.  
  876.             gGlobals->serStat.cumErrs |= swOverrunErr;
  877.             cumErrs |= swOverrunErr;
  878.                 
  879.             //    drop oldest character from our internal buffer
  880.  
  881.             gGlobals->inBufStartIndex++;
  882.             if (gGlobals->inBufStartIndex >= gGlobals->inBufLen)
  883.                 gGlobals->inBufStartIndex = 0;
  884.                 
  885.             //    we've had a software overrun -- we quit now and let the
  886.             //    client get a chance to read in the existing bytes -- 
  887.         }
  888.         
  889.         //    check for an outstanding read request
  890.         
  891.         pb = (IOParam *)gGlobals->pbIn;
  892.         if (pb)
  893.         {
  894.             //    copy bytes from input buffer into pb read buffer
  895.             //    (result is either 1=incomplete or 0=complete)
  896.     
  897.             result = HAL_FillReadRequest(pb);
  898.             
  899.             //    handle errors that cause read aborts
  900.             
  901.             if (cumErrs & gGlobals->serShk.errs) 
  902.                 result = rcvrErr;
  903.             
  904.             //    if we have fulfilled this read request, we
  905.             //  need to call IOCommandIsComplete on it
  906.             //  and continue processing with the next request
  907.             
  908.             if ( result <= noErr )
  909.             {
  910.                 gGlobals->pbIn = nil;
  911.                 break;
  912.             }
  913.         }
  914.     }
  915.     
  916.     // clean up after ourselves
  917.     if (result <= noErr)
  918.         ShimIOComplete((union ParamBlockRec *)pb, result);
  919. }